import maya.cmds as mc
class LZ_sdk_command():
    def __init__(self):
        pass
    '''
    self.setDrivenKey('xxx.translateX','bbb.translateY',driverV=0,drivenV=0)
    '''    
    def LZ_setDrivenKey(self,driverAttr,drivenAttr,driverV,drivenV):

        mc.setDrivenKeyframe(drivenAttr, cd=driverAttr,dv=driverV,v=drivenV)  
    
    
     ##  cycleRelative   cycle   constant
    def LZ_serDrivenKey_02(self,driverAttr = 'xxx.aaa', drivenAttr = 'xxx.bbb' ,driverV = [0,1] , drivenV = [ 0 , 1 ] ,inType = 'linear' ,outType = 'linear' , preV = 'cycleRelative', poiV = 'cycleRelative'):
        
        if len(driverV) == len(drivenV) :
            for i in range(len(driverV)) :
                mc.setDrivenKeyframe(  drivenAttr, cd= driverAttr,dv = driverV[i],v = drivenV[i] , inTangentType = inType ,outTangentType = outType )  
                
                ani_node = self.findNode_animation( driver = driverAttr , driven = drivenAttr )
                #print(i,ani_node)
                self.set_key_Infinity_type( aniCurve = ani_node ,priValue = preV , poiValue = poiV )
                
        
    '''


    '''
    def SDK_getDriver(self,attr):
        drivers=mc.setDrivenKeyframe(attr,q=True,dr=True)
        return drivers
    def  list_keytangent_type(self,animCurve = '', type='linear'):
        if 'animCurve' in mc.nodeType(animCurve) :
            mc.keyTangent(animCurve,itt =type,ott=type)
        else:
            print ('please make sure the object input is  animationCurve')
            
    def set_key_Infinity_type(self,aniCurve = '' ,priValue = 'cycle', poiValue = 'cycle'):  ##  cycleRelative   cycle   constant
        #print(aniCurve)
        mc.selectKey( aniCurve )
        #print(aniCurve)
        mc.setInfinity(  pri = priValue, poi = poiValue )
        
    def  set_keytangent_type(self,animCurve = '', type='linear'):
        if 'animCurve' in mc.nodeType(animCurve) :
            mc.keyTangent(animCurve,itt =type,ott=type)
        else:
            print ('please make sure the object input is  animationCurve')
            
    ####          list  SDKenAttr          
    def facial_listSDKerAttr(self,driverAttr):

        animaCurve=mc.listConnections(driverAttr,d=True,t='animCurveUL')

        if animaCurve==None:
            
            mc.textScrollList('SDKenAttrlist',ra=True,e=True)
            sys.stdout.write('there is no any setDrivenKey object')
        else:
            SDKenObj=[]
            for i in animaCurve:
                blendWeightNode=mc.listConnections(str(i)+'.output',d=True)[0]
                
                nodeblend=mc.nodeType(blendWeightNode)
                if nodeblend=='blendWeighted':
                
                    childNode=mc.listConnections(str(blendWeightNode)+'.output',d=True) 
            
                    for m in childNode:
                        
                        typenode=mc.nodeType(m)
                        
                        if typenode=='transform' or 'joint':
                            if m in SDKenObj:
                                pass
                            else:
                                SDKenObj.append(m)
                else:
                    if blendWeightNode in SDKenObj:
                            pass
                    else:
                        SDKenObj.append(blendWeightNode)

            mc.textScrollList('SDKenAttrlist',ra=True,e=True)
            mc.textScrollList('SDKenAttrlist',append=SDKenObj,e=True)    
        
    '''
    getSDKconnectionInfo(string ,driven)                string is a XXX.attribute   driven is a object name
    
    getSDKconnectionInfo('xxx.translateX' ,'sphere1')   
    '''    
    def getSDKconnectionInfo(self,driver,driven):
    
        drivers=mc.setDrivenKeyframe(driven,q=1,dr=1)
        drivenAttrs=mc.setDrivenKeyframe(driven,q=1,dn=1)
        
        AnimaCurve=[]
        driverAnimaCurve=[]
        driverCurves=[]
        
        SDKconnectionInfoAll=[]
        
        if driver in drivers:
            driverChilddren=mc.listConnections(driver,d=True,s=False)
            
            for dcr in driverChilddren:
                if mc.nodeType(dcr)=='unitConversion':
                    anicurve=mc.listConnections(str(dcr)+'.output',d=True)[0]
                    driverCurves.append(anicurve)
                elif 'animCurve' in mc.nodeType(dcr):
                    driverCurves.append(dcr)
                    
        
        for aa in drivenAttrs:
            sourceConnection=mc.listConnections(str(driven),s=True)
            
            if sourceConnection !=None:
                for sc in sourceConnection:
                
                    if 'animCurve' in mc.nodeType(sc):
                        if  sc not in AnimaCurve:
                            AnimaCurve.append(sc)
                    elif mc.nodeType(sc)=='blendWeighted':
                        curves=mc.listConnections(str(sc)+'.input',s=True)
                        for cvs in curves:
                            if  cvs not in AnimaCurve:
                                AnimaCurve.append(cvs)
                    elif mc.nodeType(sc)=='unitConversion':
                        uniInput=mc.listConnections(str(sc)+'.input',s=True)[0]
                        if mc.nodeType(uniInput)=='blendWeighted':
                            bwinput=mc.listConnections(str(uniInput)+'.input',s=True)
                            for bwi in bwinput:
                                if 'animCurve' in mc.nodeType(bwi):
                                    if  bwi not in AnimaCurve:
                                        AnimaCurve.append(bwi)
                                if mc.nodeType(bwi)=='unitConversion':
                                    bwiuniInput=mc.listConnections(str(bwi)+'.input',s=True)[0]
                                    if 'animCurve' in mc.nodeType(bwiuniInput):
                                        if  bwiuniInput not in AnimaCurve:
                                            AnimaCurve.append(bwiuniInput)
                            
        
        for ac in AnimaCurve:
            if ac in driverCurves:
                driverAnimaCurve.append(ac)
        '''
        for dac in driverAnimaCurve:
            destinationAttr='none'
            destination=mc.listConnections(str(dac)+'.output',d=True,skipConversionNodes=True)[0]
            print(destination)
            if mc.nodeType(destination)=='blendWeighted':
                destinationAttr=mc.listConnections(str(destination)+'.output',d=True,p=True,skipConversionNodes=True)[0]
            elif mc.nodeType(destination)=='transform' or mc.nodeType(destination)=='blendShape' or mc.nodeType(destination)=='joint':
                
                destinationAttr=mc.listConnections(str(dac)+'.output',d=True,p=True,skipConversionNodes=True)[0]
            
            else:
                inputAttr=mc.listConnections(str(dac)+'.output',d=True,p=True)[0]
                
                inputObj=str(inputAttr).split('.')[0]
                
                if mc.nodeType(inputObj)=='unitConversion':
                    inoutBlendweight=mc.listConnections(str(inputObj)+'.output',d=True)[0]
                    Blendweightout=mc.listConnections(str(inoutBlendweight)+'.output',d=True)[0]
                    destinationAttr=mc.listConnections(str(Blendweightout)+'.output',d=True,p=True,skipConversionNodes=True)[0]
                elif mc.nodeType(inputObj)=='blendWeighted':
                    destinationAttr=mc.listConnections(str(destination)+'.output',d=True,p=True,skipConversionNodes=True)[0]
            
        '''
        for dac in driverAnimaCurve:
            destinationAttr='none'
            destination=mc.listConnections(str(dac)+'.output',d=True,skipConversionNodes=True)[0]
            if mc.nodeType(destination)=='blendWeighted':
                destinationAttr=mc.listConnections(str(destination)+'.output',d=True,p=True,skipConversionNodes=True)[0]
            
            else:
                destinationAttr=mc.listConnections(str(dac)+'.output',d=True,p=True,skipConversionNodes=True)[0]
            
        
            SDKconnectionInfo=[driver,dac,destinationAttr]
            
            SDKconnectionInfoAll.append(SDKconnectionInfo)
        return SDKconnectionInfoAll
        
    ###------------------------------------------------------------------------------------
    
    def modify_ani_node_float(self , aini_node = '' ,float = ( 1,2) ,floatValue = 1):
        mc.keyframe( aini_node,e = True ,option = 'over' , index = float, absolute =True ,floatChange = floatValue )
    def modify_ani_node_value(self , aini_node = '' ,float = ( 1,2) ,Value = 1):
        mc.keyframe( aini_node,e = True ,option = 'over' , index = float, absolute =True ,valueChange = Value )
        
    def query_mount_keyframe(self ,aini_node = '' ):
        mount = mc.keyframe( aini_node,q = True  , keyframeCount = 1 )
        return mount
    '''
    LZ_getSDKFloat('animCurveUL6')  get the list of all floatChange  
    '''
    def LZ_getSDKFloat(self,animaNode):
        floatChange=mc.keyframe(animaNode,q=True,floatChange=True)
        return floatChange
    '''
    LZ_getSDKValue('animCurveUL6')            get the list of all valueChange  
    '''
    def LZ_getSDKValue(self,animaNode):
        valueChange=mc.keyframe(animaNode,q=True,valueChange=True)
        return valueChange
    '''
    LZ_getSDKIndex('animCurveUL6')      get the list of all indexs
    '''
    def LZ_getSDKIndex(self,animaNode):
        index=mc.keyframe(animaNode,q=True,indexValue=True)
        return index
    '''
    LZ_setKeyframe('animCurveUL6',10,5)     set the value is 5 when the floatValue is 10
    ''' 
    def LZ_setKeyframe(self,animaNode,float,value):
        mc.setKeyframe(animaNode,f=float,v=value)
    '''
    
    ''' 
    def createNodeAnima(self,type=0,name=''):
    
        if type==0:
            nodename='animCurveUA'
        else:
            nodename='animCurveUL'
        mc.createNode(nodename,n=name)
        
    def SDK_cutKey(self,animaNode,fload=(999,1000)):
        mc.cutKey(animaNode,f=fload)
        

        
    def SDK_getWeightName(self,blendShapeNode):
        aliases=mc.aliasAttr(blendShapeNode,q=True)
        blendshapeTarget=[]
        for bt in range(len(aliases)/2):
            blendshapeTarget.append(aliases[bt*2])
        return(blendshapeTarget)
    
    def findNode_animation(self,driver = 'xxx.bb' , driven = 'xx.aa' ):
        
        drivenobj = str(driven).split('.')
        

        info = self.getSDKconnectionInfo( driver,drivenobj[0])
        
        for io in info:
            #print(io[2],driven)
            
            if io[2] == driven:
                
                #print(io)
                return io[1] 
        
        
        
    #def IsSDK(self):
    def facial_combine_drive(self, driver = [('xxx.rotateX',[0,1])] ,drivenAttr = ('xxx.translateX',[0,10])):
        
        if len( driver ) > 1:
            num_all_md_combineMd = []
        
            md_name_Pre = drivenAttr[0].replace('.','_')
            isContinue = True
            
            if mc.listConnections(drivenAttr[0],s=True) != None :
            
                md_node_Exists = mc.ls(str(md_name_Pre) + '*_combine_md',type='multiplyDivide')
                    
                for mne in md_node_Exists:
                    num_md = str(mne).split('_')[-3]
                    try :
                        get_num = int(num_md)
                        num_all_md_combineMd.append(get_num)
                    except:
                        pass
            
            
                inputNode = mc.listConnections( drivenAttr[0] ,s=True ,d=False,skipConversionNodes = True)
                
                
                if mc.nodeType(inputNode) == 'blendWeighted' or   'animCurve' in mc.nodeType(inputNode) :
                    
                    isContinue = True
                else:
                    isContinue = False
                    sys.stderr.write('there is an attribute input has connected it \n')
            else:
                isContinue = True
            
            if isContinue == True:
            
                md_node_all = []
                if len(num_all_md_combineMd)==0:
                
                    for num in range(len( driver )-1):
                        
                        md_name = drivenAttr[0].replace('.','_') + '_' + str(num) +'_combine_md'
                        md_node_all.append(md_name)
                else:
                    for num in range(len( driver )-1):
                        
                        for i in range(len(num_all_md_combineMd)):
                            if num in num_all_md_combineMd:
                                num_md_combine = num
                                
                                break
                        md_name = drivenAttr[0].replace('.','_') + '_' + str(num_md_combine) +'_combine_md'
                        md_node_all.append(md_name)
                
                for mna in range( len(md_node_all)):
                    md_before_name = ''
                    if mna == 0 :
                        md_before  =  md_node_all[mna]
                    else:
                        md_before_name = md_before 
                    
                    md_node_name = mc.createNode( 'multiplyDivide' , n = md_node_all[mna] )
                    
                    md_before = md_node_name 
                    
                    input_attr01 = str(md_node_name) + '.input1.input1X'
                    input_attr02 = str(md_node_name) + '.input2.input2X'
                    
                    output_attr = str(md_node_name) + '.outputX'
                    output_attr_before = str(md_before_name) + '.outputX'
                    
                    for num_attr in range(2):
                        if num_attr == 0:
                            driven_value = 0
                        else:
                            driven_value = 1
                    
                        if mna == 0:
                            self.LZ_setDrivenKey( driverAttr= driver[mna][0] ,drivenAttr = [input_attr01],driverV=driver[mna][1][num_attr] ,drivenV= driven_value )
                            sdk_info = self.getSDKconnectionInfo( driver[mna][0] , md_node_name )
                            self.set_keytangent_type( animCurve =  sdk_info[0][1], type='linear')
                            
                        else:           #LZ_setDrivenKey(self,driverAttr,drivenAttr,driverV,drivenV)
                            
                            self.LZ_setDrivenKey( driverAttr= output_attr_before ,drivenAttr = [input_attr01] ,driverV = driven_value ,drivenV= driven_value)
                            sdk_info = self.getSDKconnectionInfo( output_attr_before , md_node_name )

                            self.set_keytangent_type( animCurve =  sdk_info[0][1], type='linear')
                            
                            
                        self.LZ_setDrivenKey( driverAttr= driver[mna+1][0] ,drivenAttr = [input_attr02],driverV=driver[mna+1][1][num_attr] ,drivenV= driven_value )
                        
                        sdk_info = self.getSDKconnectionInfo( driver[mna+1][0] , md_node_name )
                        self.set_keytangent_type( animCurve =  sdk_info[0][1], type='linear')
                
                self.LZ_setDrivenKey( driverAttr= output_attr ,drivenAttr = [drivenAttr[0]],driverV = 0,drivenV= drivenAttr[1][0] )
                
                
                sdk_info = self.getSDKconnectionInfo( output_attr, drivenAttr[0].split('.')[0] )
                self.set_keytangent_type( animCurve =  sdk_info[0][1], type='linear')

                self.LZ_setDrivenKey( driverAttr= output_attr ,drivenAttr = [drivenAttr[0]],driverV = 1,drivenV= drivenAttr[1][1] )
                
                sdk_info = self.getSDKconnectionInfo( output_attr, drivenAttr[0].split('.')[0] )
                self.set_keytangent_type( animCurve =  sdk_info[0][1], type='linear')